/* end.h - Structure for the MUX and END API*/

/*
 * Copyright (c) 1996-2005 Wind River Systems, Inc.
 *
 * The right to copy, distribute, modify or otherwise make use
 * of this software may be licensed only pursuant to the terms
 * of an applicable Wind River license agreement.
 */

/*
modification history
--------------------
03q,31aug05,kch  Renamed END_ERR_IFMTU_CHANGE to END_ERR_L2NOTIFY. Added
                 l2notify_params structure definition (SPR #112068).
03p,29aug05,dlk  Move END_RCVJOBQ_INFO definition here from endCommon.h, as
                 it is not usable from user space. Add jobQueueLib.h include.
03o,23aug05,kch  Added END_ERR_IFMTU_CHANGE define.
03n,14aug05,niq  Add parameters for ingress QOS support
03m,03aug05,kch  Added endObjId to END_OBJ. Also modified formAddress and
                 packetDataGet function pointers in NET_FUNCS to have 
                 unspecified argument list.
03l,24jun05,wap  Add ifmedia support
03k,21feb05,dlk  Move selected parts of this file to endCommon.h, to support
		 tunnelled END ioctls.
03j,25nov03,wap  Merge in changes from Snowflake
03i,29sep03,rp   merged from base6_networking_itn2-int
03h,13jan03,rae  Merged from velocecp branch
03g,23oct01,rae  merge from truestack (fix some ioctl values)
03f,16oct01,rcs  added END_ERR_NO_BUF flag to notify mux of driver cluster
                 exhaustion. SPR# 70545
01z,13jul01,ann  added a flag for RFC2233 driver support to eliminate the
                 global mibStyle variable
03e,09nov00,spm  removed pNptCookie from END_OBJ for binary compatibility
03d,07nov00,spm  removed nptFlag from END_OBJ for T2 END binary compatibility
03d,25oct00,niq  Merge RFC2233 changes from open_stack-p1-r1 branch
                 03c,10mar00,ead  Modifed the END object to support RFC 
                 variables
03c,16oct00,spm  merged version 01v from tor3_0_x branch (base version 01r):
                 adds backward compatibility fixes and support for multiple
                 snarf protocols and link-level broadcasts
03b,29apr99,pul  Upgraded NPT phase3 code to tor2.0.0
03a,29mar99,pul  altered END_QUERY struct to conform to WRS coding standard
02z,24mar99,sj   NET_PROTOCOL flags field is used by MUX
02y,05mar99,sj   added END_QUERY; added END_ERR_FLAGS
02x,02mar99,sj   fixed IOCTL values so that last byte of IOCTL cmd is <255
02w,22feb99,sj   added EIOCGBCASTADDR, EIOCGADDRLEN, EIOCGBIND ioctls
01v,15oct98,pul  changed the call back routines not to specify argument list 
01u,08oct98,sj   EIOCGNPT ioctl command for NPT
01t,29sep98,fle  doc : made it refgen parsable
01s,10sep98,pul  added endBind  and EIOCGNPT command
01r,25aug98,n_s  update comments for DEV_OBJ. spr 21546.
01q,17jan98,gnn  fixed a bug in output filtering.
01p,08dec97,gnn  END code review fixes.
01o,17oct97,vin  added llHdrInfo, changed prototypes.
01n,03oct97,gnn  fixed SPR 8986, added proper function prototypes
01m,25sep97,gnn  SENS beta feedback fixes
01l,19aug97,gnn  changes due to new buffering scheme.
01k,12aug97,gnn  changes necessitated by MUX/END update.
01j,02jun97,gnn  added EIOCGMWIDTH to get memory width from driver.
01i,15may97,gnn  added outputFilter element to device structure.
01h,07apr97,gnn  added END_TBL_ENTRY for new boot loading code.
01g,26feb97,gnn  Added END_BUF_MUX and END_BUF_DRIVER defines.
01f,21jan97,gnn  removed all buffer loaning stuff.
                 added buffer pool variables and calls.
                 added a IOCTL to get the minimumb first buffer in a
                 scatter/gather system.
01e,27nov96,gnn  added MIB 2 Ioctl.
01d,07nov96,gnn  fixed the flags fields to be int.
01c,23oct96,gnn  name changes to follow coding standards.
01b,22oct96,gnn  added pragmas for the i960.
                 removed netVector structure and added a pNext pointer
                 to the NET_BUFFER.
                 added function pointers for the start and stop routines.
                 changed the ioctls to be noun->verb
01a,18apr96,gnn	 written.

*/
 
/*
DESCRIPTION

This file defines all the structures uses by the MUX and any END.  These
structures are either passed by functions in either the MUX or END
or stored by the MUX.
*/

#ifndef __INCendh
#define __INCendh

#include <endCommon.h>
#include <semLib.h>
#include <memLib.h>
#include <netBufLib.h>
#include <net/if_llc.h>
#include <jobQueueLib.h> /* For JOB_QUEUE_ID */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * ERROR Return for device blocked on transmit.
 */

#define END_ERR_BLOCK -2

/*
 * ERROR protocol defines.  These are stored in a 32 bit word in the
 * end_err structure.  User apps can have the upper 16 bits, we get the
 * lower 16.
 *
 * Note that the LINKDOWN and LINKUP error codes are semantically
 * different from UP and DOWN. The former indicate a link change event
 * due to cable disconnection, remote end fault or signal loss, while
 * the latter indicate administrative changes in the interface state,
 * such as the stop/start routines in the driver being manually invoked
 * by the user. It is possible for the interface to be administratively
 * up (chip is turned on and running) but still issue a link down event
 * (e.g. if the cable is suddenly unplugged).
 */
#define END_ERR_INFO     1   /* Information only */
#define END_ERR_WARN     2   /* Warning */
#define END_ERR_RESET    3   /* Device has reset. */
#define END_ERR_DOWN     4   /* Device has gone down. */
#define END_ERR_UP       5   /* Device has come back on line. */
#define END_ERR_FLAGS	 6   /* Device flags changed */
#define END_ERR_NO_BUF   7   /* Device's cluster pool exhausted. */
#define END_ERR_LINKDOWN 8   /* Device's link is down */
#define END_ERR_LINKUP   9   /* Device's link is up */
#define END_ERR_L2NOTIFY 10  /* layer 2 notification */

typedef struct end_err
    {
    INT32 errCode;           /* Error code, see above. */
    char* pMesg;             /* NULL terminated error message */
    void* pSpare;            /* Pointer to user defined data. */
    } END_ERR;
    
/* 
 * The L2NOTIFY_PARAMS is used for the END_ERR_L2NOTIFY. When the message
 * END_ERR_L2NOTIFY is sent, it is the pSpare pointer in the END_ERR
 * which points to an L2NOTIFY_PARAMS. 
 *
 * <l2Attached> sets to true if a port is attached to the layer 2, false
 * if the port is detached from layer 2. If <l2Attached> is true for END
 * device, the interface's if_output routine is expected to use the  
 * pEnd->pFuncTable->formAddress to construct its ethernet header. For
 * NPT-style device, the <l2Attached> should be ignore for now (actual
 * bahavior is currently not defined).
 *
 * <newMtu> indicates the mtu size upper layer protocols (e.g. IP) should 
 * apply to the interface. The newMtu size will be set to the existing 
 * hardware mtu size if the following applies:
 * 1) hardware indicates it supports hardware VLAN tagging (e.g. the 
 *    IFCAP_VLAN_HWTAGGING in if_capabilities is set), or
 * 2) hardware doesn't support hardware VLAN tagging but capable of handling 
 *    larger mtu that may include a software-appended VLAN header (e.g. the
 *    IFCAP_VLAN_MTU flag is set in if_capabilities)
 * If none of the above is true, the existing hardware mtu size will be
 * reduced by 4 bytes and reflects in <newMtu>.
 */
typedef struct l2notify_params {
    BOOL l2Attached;  /* true if port is attached to layer 2, false if detach */
    unsigned long newMtu; 
} L2NOTIFY_PARAMS;

/* A specific instance of an Ethernet multicast address. */
typedef struct 
    {
    NODE node;		     /* How we stay in a list. */
    char  addr[6];	     /* address */
    long   refcount;	     /* no. claims to this addr*/
    } ETHER_MULTI; 

typedef struct 
    {
    long len;		/* Length of table in bytes. */
    char *pTable;		/* Pointer to entries. */
    } MULTI_TABLE;

/* structure used as a vehicle to move data during a EIOCQUERY ioctl */

typedef struct
    {
    int query;		/* the query */
    int queryLen;	/* length of data expected/returned */
    char queryData[4]; /* allocate a minimum of 4 bytes; expandable upto 120 */
    } END_QUERY;

/* Query system Query commands */

#define END_BIND_QUERY 0x1

/*
 *
 * DEV_OBJ - device specific control object
 *
 * The DEV_OBJ structure is the glue linking the device generic END_OBJ 
 * structure with the device specific data object referenced by pDevice.
 */

typedef struct dev_obj 
    {
    char name[END_NAME_MAX];
    int unit;
    char description[END_DESC_MAX];
    void* pDevice;		/* Pointer back to the device data. */
    } DEV_OBJ;
	
/*
* 
* LL_HDR_INFO - link level Header info 
*
* This data structure defines information that is only relevant to
* a stack receive routine.
*
*/

typedef struct llHdrInfo
    {
    int		destAddrOffset;		/* destination addr offset in mBlk */
    int		destSize; 		/* destination address size */
    int		srcAddrOffset;		/* source address offset in mBlk */
    int		srcSize;		/* source address size */
    int		ctrlAddrOffset;		/* control info offset in mBlk */
    int		ctrlSize;		/* control info size */
    int		pktType;		/* type of the packet */
    int		dataOffset;		/* data offset in the mBlk */
    } LL_HDR_INFO;

struct proto_entry;
struct protocol_binding;

/*
 *
 * endObject - the basic end object that everyone derives from
 *
 * This data structure defines a device independant amount of state
 * that is maintained by all drivers/devices.
 * Each specific device (Lance, Intel, etc.) derives from this object
 * first and then incorporates it's own data structures after it.
 *
 */
typedef struct end_object
    {
    NODE node;
#ifndef _WRS_VXWORKS_5_X
    BOOL nptFlagSpace;          /* Had indicated type of interface: END or NPT. Now: UNUSED */
#endif /* _WRS_VXWORKS_5_X */
    DEV_OBJ devObject;		/* Root of the device heirarchy. */
    STATUS (*receiveRtn) ();    /* MUX routine to call on reception. */
    struct proto_entry * pSnarf;   /* First snarf protocol */
    struct proto_entry * pTyped;   /* First typed protocol */
    struct proto_entry * pPromisc; /* First promiscuous protocol */
    struct proto_entry * pStop;          /* End of protocols */
    UINT32 nProtoSlots;               /* Number of slots in protocol table */
    int endStyle;             /* END, NPT, MULTI, ... */
    BOOL attached;            /* Indicates unit is attached. */

    SEM_ID txSem;		/* Transmitter semaphore. */
    long flags;			/* Various flags. */
    struct net_funcs *pFuncTable;	/* Function table. */
    M2_INTERFACETBL mib2Tbl;	/* MIBII counters. */
    LIST multiList;		/* Head of the multicast address list */
    int	nMulti;			/* Number of elements in the list. */
    struct protocol_binding * outputFilter; /* Optional output filter */
    NET_POOL_ID pNetPool;       /* Memory cookie used by MUX buffering. */
    M2_ID * pMib2Tbl;           /* RFC 2233 MIB objects */
    struct end_object * dummyBinding; /* dummy protocol binding */

    unsigned short endObjId;     /* END/NPT device ID for Layer 2 */
/* #ifdef QOS */
    STATUS (*origReceiveRtn) (); /*Original MUX routine to call on reception.*/
    int (*qosHookRtn) ();        /* Packet classifier hook routine. */
/* #endif /@ QOS @/ */
    } END_OBJ;

/*
 * 
 * NET_FUNCS - driver function table
 *
 * This is a table that is created, one per driver, to hold all the
 * function pointers for that driver.  In this way we can have only one
 * instance to this structer, but one pointer per netDevice structure.
 */

typedef struct net_funcs
    {
    STATUS (*start) (END_OBJ*);		   /* Driver's start func. */
    STATUS (*stop) (END_OBJ*);		   /* Driver's stop func. */
    STATUS (*unload) (END_OBJ*);		   /* Driver's unload func. */
    int (*ioctl) (END_OBJ*, int, caddr_t);    /* Driver's ioctl func. */
    STATUS (*send) (END_OBJ* , M_BLK_ID);	   /* Driver's send func. */
    STATUS (*mCastAddrAdd) (END_OBJ*, char*); /* Driver's mcast add func. */
    STATUS (*mCastAddrDel) (END_OBJ*, char*); /* Driver's mcast delete func. */
    STATUS (*mCastAddrGet) (END_OBJ*, MULTI_TABLE*);
                                           /* Driver's mcast get fun. */
    STATUS (*pollSend) (END_OBJ*, M_BLK_ID);  /* Driver's polling send func. */
    STATUS (*pollRcv) (END_OBJ*, M_BLK_ID);   /* Driver's polling recv func. */

    /* 
     * The minimum required arguments for (*formAddress)() are: 
     * (*formAddress)(M_BLK_ID, M_BLK_ID, M_BLK_ID, BOOL)
     */
    M_BLK_ID (*formAddress) ();         /* Driver's addr formation func. */

    /*
     * The minimum required arguments for (*packetDataGet)() are
     * (*packetDataGet)(M_BLK_ID, LL_HDR_INFO *)
     */
    STATUS (*packetDataGet) ();         /* Driver's packet data get func. */
    STATUS (*addrGet) (M_BLK_ID, M_BLK_ID, M_BLK_ID, M_BLK_ID, M_BLK_ID);
                                           /* Driver's packet addr get func. */
    int (*endBind) (void*, void*, void*, long type); 
					/* information exchange between */
					/* network service and network driver */ 
    } NET_FUNCS; 


/* This structure is a row in our run time END table. 
 * Each row contains all the units started on a particular named device.
 * I.e. all devices that are Lance 7990 Ethernet will be in the list
 * off of the row with the name "ln".
 */

typedef struct end_tbl_row
    {
    NODE node;                  /* Needed by our list processing library. */
    char name[END_NAME_MAX];	/* Name of the devices in row. (ln, etc.) */
    LIST units;                 /* List of devices, i.e. 0, 1, etc..  */
    } END_TBL_ROW;

/* This is the structure that is used by the BSP to build up a table
 * of END devices to be started at boot time.
 */
typedef struct end_tbl_entry
    {
    int unit;                                /* This device's unit # */
    END_OBJ* (*endLoadFunc) (char*, void*);         /* The Load function. */
    char* endLoadString;                     /* The load string. */
    BOOL endLoan;                            /* Do we loan buffers? */
    void* pBSP;                              /* BSP private */
    BOOL processed;                          /* Has this been processed? */
    } END_TBL_ENTRY;
    
#define END_TBL_END NULL

/*
 * Definitions and structures for polled stats counters.
 */

typedef unsigned long long endCounter;

typedef struct /*endIfCounters*/
    {
    endCounter		ifInErrors;
    endCounter		ifInDiscards;
    endCounter		ifInUnknownProtos;
    endCounter		ifInOctets;
    endCounter		ifInUcastPkts;
    endCounter		ifInMulticastPkts;
    endCounter		ifInBroadcastPkts;

    endCounter		ifOutErrors;
    endCounter		ifOutDiscards;
    endCounter		ifOutOctets;
    endCounter		ifOutUcastPkts;
    endCounter		ifOutMulticastPkts;
    endCounter		ifOutBroadcastPkts;
    } END_IFCOUNTERS;

#define END_IFINERRORS_VALID		0x00000001
#define END_IFINDISCARDS_VALID		0x00000002
#define END_IFINUNKNOWNPROTOS_VALID	0x00000004
#define END_IFINOCTETS_VALID		0x00000008
#define END_IFINUCASTPKTS_VALID		0x00000010
#define END_IFINMULTICASTPKTS_VALID	0x00000020
#define END_IFINBROADCASTPKTS_VALID	0x00000040

#define END_IFOUTERRORS_VALID		0x00010000
#define END_IFOUTDISCARDS_VALID		0x00020000
#define END_IFOUTUNKNOWNPROTOS_VALID	0x00040000
#define END_IFOUTOCTETS_VALID		0x00080000
#define END_IFOUTUCASTPKTS_VALID	0x00100000
#define END_IFOUTMULTICASTPKTS_VALID	0x00200000
#define END_IFOUTBROADCASTPKTS_VALID	0x00400000

typedef struct /*endIfDrvConf*/
    {
    int			ifPollInterval;
    UINT32		ifValidCounters;
    void *		ifWatchdog;
    END_OBJ *		ifEndObj;
    void *		ifMuxCookie;
    FUNCPTR		ifPollRtn;
    } END_IFDRVCONF;

/*
 * Structure used by EIOCGRCVJOBQ ioctl to retrieve the IDs of job queues
 * used by an END interface to deliver packets to the stack.  In the
 * future we may support multiple job queues per interface; at present,
 * there is a limit of just one.  However, the ioctl interface is capable
 * of reporting more than one.
 *
 * The MUX initializes numRcvJobQs with the number of available slots
 * in the array qIds.  The driver checks numRcvJobQs; if this is less
 * than the actual number of job queues used by the interface to deliver
 * received packets to the stack, the driver sets numRcvJobQs to the actual
 * number of queues it uses, returns ENOSPC, and does not modify the array
 * qIds. Otherwise, numRcvJobQs is greater than or equal to the number of
 * receive job queues used by the interface, and the driver should write
 * the actual number of queues into numRcvJobQs, write the JOB_QUEUE_IDs
 * of the queues into the initial elements of the array qIds in any convenient
 * order, and return OK.
 *
 * AT PRESENT, ONLY ONE RECEIVE JOB QUEUE IS PERMITTED PER INTERFACE.
 *
 * Defined here rather than in endCommon.h since the job queue IDs aren't
 * usable in user space.
 */

typedef struct _END_RCVJOBQ_INFO
    {
    UINT32 numRcvJobQs;    /* # job qs on which interface delivers packets */
    JOB_QUEUE_ID qIds [1]; /* variable length array of job queue IDs. */
    } END_RCVJOBQ_INFO;

#ifdef __cplusplus
}
#endif

#endif /* __INCendh */
